home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 July / EnigmA AMIGA RUN 09 (1996)(G.R. Edizioni)(IT)[!][issue 1996-07 & 08][EARSAN CD VIII].iso / earcd / util3 / fiflb382.lha / remcli.c < prev    next >
C/C++ Source or Header  |  1996-05-14  |  8KB  |  388 lines

  1.  
  2. /*
  3.  *  REMCLI.C
  4.  *
  5.  *  REMCLI <fifo_name>
  6.  *
  7.  *  PUBLIC DOMAIN CODE, sample code showing how to set up a remote CLI
  8.  *  through the FIFO: device, using fifo.library to handle the master
  9.  *  end.
  10.  *
  11.  *  WARNING:    ReadFifo() returns an EOF condition (-1) only once,
  12.  *        calling it again will return 0 .. blocking until a
  13.  *        writer writes something then closes again to generate
  14.  *        another EOF.
  15.  *        Huh? Clearing FIFOF_EOF is commented out in fifo.c so
  16.  *        that EOF is reported every time.  See TODO (Jörg Höhle)
  17.  */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/io.h>
  21. #include <exec/memory.h>
  22. #include <devices/conunit.h>
  23. #include <intuition/intuition.h>
  24. #include <libraries/dos.h>
  25. #include <libraries/fifo.h>
  26. #if defined(_DCC) /*  at least the very old DICE 2.06 */
  27. #include <clib/exec_protos.h>
  28. #include <clib/dos_protos.h>
  29. #include <clib/intuition_protos.h>
  30. #else
  31. #include <proto/exec.h>
  32. #include <proto/dos.h>
  33. #include <proto/intuition.h>
  34. #endif
  35. #include <clib/alib_protos.h>
  36. #include <proto/fifo.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <fcntl.h>        /*  write() */
  41. #if defined(__GNUC__)
  42. #include <unistd.h>        /*  write() */
  43. #endif
  44. #ifdef USE_SIGNAL
  45. #include <signal.h>
  46. #endif
  47.  
  48. typedef unsigned char    ubyte;
  49. typedef unsigned short    uword;
  50. typedef unsigned long    ulong;
  51. typedef struct MsgPort        MsgPort;
  52.  
  53. typedef struct Task        Task;
  54. typedef struct Process        Process;
  55. typedef struct Window        Window;
  56. typedef struct IOStdReq     Ioc;
  57. typedef struct Message        Message;
  58. typedef struct IntuiMessage IMess;
  59. typedef struct IORequest    IORequest;
  60.  
  61. Ioc    Iocr;
  62. Ioc    Iocw;
  63. Message RMsg;
  64. Message WMsg;
  65. Window    *Win;
  66. char    *FifoName;    /*  fifo    */
  67. char    *FifoSlav;    /*  fifo_s  */
  68. char    *FifoMast;    /*  fifo_m  */
  69. char    *ErrBuf;
  70. MsgPort *IoSink;
  71. char    ConBuf[32];
  72. void    *FifoR;
  73. void    *FifoW;
  74. struct Library *FifoBase;
  75. struct IntuitionBase *IntuitionBase;
  76.  
  77. char    IocrIP;     /*  console read pending*/
  78. char    IocrHold;
  79. char    FifrIP;     /*  read msg pending    */
  80. char    FifwIP;     /*  write msg pending    */
  81. short    Done = 0;
  82.  
  83. struct NewWindow Nw = {
  84.     0, 0, 640, 200, -1, -1,
  85.     CLOSEWINDOW|MENUPICK|GADGETUP|GADGETDOWN|NEWSIZE,
  86.     WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|
  87.     NOCAREREFRESH|ACTIVATE,
  88.     NULL, NULL, (ubyte *)"RemCLI", NULL, NULL, 32, 32, -1, -1, WBENCHSCREEN
  89. };
  90.  
  91. const char verstring[] = "\0$VER: RemCLI 38.1 (20.12.95)\r\n";
  92.  
  93. #define errline(s,len) write(2, s, len)
  94. #define errmsg(s) errline(s, sizeof(s)-1)
  95. #define errmsg1(s,v) {int errlen = sprintf(ErrBuf, s, v); errline(ErrBuf, errlen);}
  96.  
  97. void ConWriteStr(char *);
  98. void ConWrite(void *, long);
  99. void SendBreak(int);
  100. void myexit(void);
  101. void WaitMsg(Message *);
  102. #ifndef USE_SIGNAL
  103. #ifdef _DCC
  104. int  brk(void);
  105. #endif
  106. #if defined(__GNUC__)        /*  actually libnix only */
  107. void __chkabort(void);
  108. #endif
  109. #endif
  110.  
  111. int main(int ac, char **av)
  112. {
  113.     long imask;
  114.     long pmask;
  115.  
  116.     if (ac != 2) {
  117.     errmsg("Demonstration Remote Shell through FIFO:\n");
  118.     errmsg("Instructions:\n");
  119.     errmsg("  1> NewShell FIFO:name/rwkecs\n");
  120.     errmsg("  1> Run >NIL: RemCLI name\n");
  121.     exit(1);
  122.     }
  123.     atexit(myexit);
  124. #ifndef USE_SIGNAL
  125. #ifdef _DCC
  126.     onbreak(brk);        /*  onbreak() generates shorter code than signal() */
  127. #endif
  128. #else
  129.     signal(SIGINT, SIG_IGN);
  130. #endif
  131.  
  132.     FifoName = av[1];
  133.     {
  134.     int len  = strlen(FifoName);
  135.  
  136.     FifoSlav = malloc(len + (len<<1) + (3 + 3 + 35));
  137.     FifoMast = FifoSlav + len + 3;
  138.     ErrBuf   = FifoMast + len + 3;
  139.     }
  140.     sprintf(FifoMast, "%s_m", FifoName);
  141.     sprintf(FifoSlav, "%s_s", FifoName);
  142.  
  143.     IoSink = CreatePort(NULL, 0);
  144.  
  145.     /*
  146.      *    FIFOS
  147.      */
  148.  
  149.     FifoBase = OpenLibrary(FIFONAME, 0);
  150.     if (!FifoBase) {
  151.     errmsg1("unable to open %s\n", FIFONAME);
  152.     exit(1);
  153.     }
  154.     FifoW = OpenFifo(FifoMast, 2048, FIFOF_WRITE | FIFOF_NORMAL | FIFOF_NBIO);
  155.     if (FifoW == NULL) {
  156.     errmsg1("unable to open fifo %s\n", FifoMast);
  157.     exit(1);
  158.     }
  159.     FifoR = OpenFifo(FifoSlav, 2048, FIFOF_READ  | FIFOF_NORMAL | FIFOF_NBIO);
  160.     if (FifoR == NULL) {
  161.     errmsg1("unable to open fifo %s\n", FifoSlav);
  162.     exit(1);
  163.     }
  164.     RMsg.mn_ReplyPort = IoSink;
  165.     WMsg.mn_ReplyPort = IoSink;
  166.  
  167.     /*
  168.      *    WINDOW
  169.      */
  170.  
  171.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  172.     if (!IntuitionBase) {
  173.     errmsg("unable to open intuition.library\n");
  174.     exit(1);
  175.     }
  176.  
  177.     Win = OpenWindow(&Nw);
  178.     if (Win == NULL) {
  179.     errmsg("unable to open window!\n");
  180.     exit(1);
  181.     }
  182.     imask = 1 << Win->UserPort->mp_SigBit;
  183.     pmask = 1 << IoSink->mp_SigBit;
  184.  
  185.     /*
  186.      *    CONSOLE DEVICE
  187.      */
  188.  
  189.     Iocw.io_Message.mn_ReplyPort = IoSink;
  190.     Iocw.io_Data = (APTR)Win;
  191.     Iocw.io_Length = sizeof(*Win);
  192.     if (OpenDevice("console.device", 0, (IORequest *)&Iocw, 0)) {
  193.     errmsg("can't open console!\n");
  194.     exit(1);
  195.     }
  196.     Iocr = Iocw;
  197.     Iocw.io_Command = CMD_WRITE;
  198.     Iocr.io_Command = CMD_READ;
  199.  
  200.     Iocr.io_Data = (APTR)ConBuf;
  201.     Iocr.io_Length = 1;
  202.     SendIO((IORequest *)&Iocr);
  203.     IocrIP = 1;
  204.  
  205.     /*
  206.      *    start async FIFO requests
  207.      */
  208.  
  209.     RequestFifo(FifoR, &RMsg, FREQ_RPEND);
  210.     FifrIP = 1;
  211.  
  212.     /*
  213.      * start shell for slave side
  214.      */
  215.  
  216.     while (!Done) {
  217.     long mask = Wait(imask | pmask);
  218.  
  219. top:
  220.     if (mask & imask) {
  221.         IMess *im;
  222.  
  223.         while ((im = (IMess *)GetMsg(Win->UserPort))) {
  224.         switch(im->Class) {
  225.         case CLOSEWINDOW:
  226.             Done = 2;
  227.             mask = 0;
  228.             break;
  229.         case NEWSIZE:
  230.             ConWriteStr("\017\233\164\233\165\233\166\233\167");
  231.             break;
  232.         }
  233.         ReplyMsg((Message *)im);
  234.         }
  235.     }
  236.     if (mask & pmask) {
  237.         Message *msg;
  238.         int n;
  239.  
  240.         while ((msg = (Message *)GetMsg(IoSink))) {
  241.         if (msg == (Message *)&Iocr) {
  242.             IocrIP = 0;
  243.             if (Iocr.io_Actual > 0) {
  244.             switch(*(char *)Iocr.io_Data) {
  245.             case 3:
  246.                 SendBreak('C');
  247.                 break;
  248.             case 4:
  249.                 SendBreak('D');
  250.                 break;
  251.             case 5:
  252.                 SendBreak('E');
  253.                 break;
  254.             case 6:
  255.                 SendBreak('F');
  256.                 break;
  257.             default:
  258.                 n = WriteFifo(FifoW, Iocr.io_Data, Iocr.io_Actual);
  259.                 if (n != Iocr.io_Actual) {
  260.                 IocrHold = 1;
  261.                 if (FifwIP == 0) {
  262.                     RequestFifo(FifoW, &WMsg, FREQ_WAVAIL);
  263.                     FifwIP = 1;
  264.                 }
  265.                 }
  266.                 break;
  267.             }
  268.             }
  269.             if (IocrHold == 0) {
  270.             Iocr.io_Data = (APTR)ConBuf;
  271.             Iocr.io_Length = 1;
  272.             SendIO((IORequest *)&Iocr);
  273.             IocrIP = 1;
  274.             }
  275.         } else
  276.         if (msg == (Message *)&RMsg) {
  277.             char *ptr;
  278.             long n;
  279.  
  280.             FifrIP = 0;
  281.  
  282.             if ((n = ReadFifo(FifoR, &ptr, 0)) > 0) {
  283.             if (n > 256)                /*  limit size      */
  284.                 n = 256;
  285.             ConWrite(ptr, n);
  286.                             /*    clear N bytes    */
  287.             n = ReadFifo(FifoR, &ptr, n);
  288.             }
  289.             if (n < 0) {            /*  EOF */
  290.             ConWriteStr("REMOTE EOF!\n");
  291.             Done = 1;
  292.             } else {
  293.             RequestFifo(FifoR, &RMsg, FREQ_RPEND);
  294.             FifrIP = 1;
  295.             }
  296.         } else
  297.         if (msg == (Message *)&WMsg) {
  298.             FifwIP = 0;
  299.             if (IocrHold) {                 /*  retry rd process */
  300.             ReplyMsg(&Iocr.io_Message);
  301.             IocrHold = 0;
  302.             }
  303.         }
  304.         goto top;
  305.         }
  306.     }
  307.     }
  308. }
  309.  
  310. void myexit(void)
  311. {
  312.     if (IocrIP) {
  313.     AbortIO((IORequest *)&Iocr);
  314.     WaitIO((IORequest *)&Iocr);
  315.     }
  316.     if (Iocr.io_Device)
  317.     CloseDevice((IORequest *)&Iocr);
  318.  
  319.     if (FifrIP) {
  320.     RequestFifo(FifoR, &RMsg, FREQ_ABORT);
  321.     WaitMsg(&RMsg);
  322.     }
  323.     if (FifwIP) {
  324.     RequestFifo(FifoW, &WMsg, FREQ_ABORT);
  325.     WaitMsg(&WMsg);
  326.     }
  327.     if (FifoR)
  328.     CloseFifo(FifoR, FIFOF_EOF);
  329.     if (FifoW)
  330.     /*  no FIFOF_EOF on CLOSEWINDOW to conform to documentation */
  331.     CloseFifo(FifoW, Done == 2 ? 0 : FIFOF_EOF);
  332.     if (FifoBase)
  333.     CloseLibrary(FifoBase);
  334.     if (IntuitionBase)
  335.     CloseLibrary((struct Library *)IntuitionBase);
  336.  
  337.     if (Win)
  338.     CloseWindow(Win);
  339.     if (IoSink)
  340.     DeletePort(IoSink);
  341. }
  342.  
  343. void ConWriteStr(char *buf)
  344. {
  345.     ConWrite(buf, strlen(buf));
  346. }
  347.  
  348. void ConWrite(void *buf, long len)
  349. {
  350.     Iocw.io_Data = (APTR)buf;
  351.     Iocw.io_Length = len;
  352.     DoIO((IORequest *)&Iocw);
  353. }
  354.  
  355. #ifndef USE_SIGNAL
  356. #ifdef _DCC
  357. int brk(void)
  358. {
  359.     return(0);            /*  ignore ^C */
  360. }
  361. #endif
  362. #if defined(__GNUC__)        /*  libnix internal function */
  363. void __chkabort(void)
  364. {
  365. }
  366. #endif
  367. #endif
  368.  
  369. void WaitMsg(Message *msg)
  370. {
  371.     while (msg->mn_Node.ln_Type == NT_MESSAGE)
  372.     Wait(1 << msg->mn_ReplyPort->mp_SigBit);
  373.     Forbid();
  374.     Remove(&msg->mn_Node);
  375.     Permit();
  376. }
  377.  
  378. void SendBreak(int c)
  379. {
  380.     char buf[256];
  381.     long fh;
  382.  
  383.     sprintf(buf, "FIFO:%s/%c", FifoName, c);
  384.     if ((fh = Open(buf, 1005)))
  385.     Close(fh);
  386. }
  387.  
  388.